#include "YGDGame.h"

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            //Cleanup();
            PostQuitMessage( 0 );
            return 0;

    }
    
    return DefWindowProc( hWnd, msg, wParam, lParam );
}


YGDGame::YGDGame(HINSTANCE hInst, HINSTANCE hPrevInst, wchar_t * lpCmdLine, int nCmdShow,const char* windowName, const char* windowTitle)
{
	if(0 == (pEngine=getYGDEngine(hInst,hPrevInst,lpCmdLine,nCmdShow,MsgProc,windowName,windowTitle)))
	{
    exit(1);
	}

	HWND hWnd=pEngine->getWindowIdentifier();
	ShowWindow( hWnd, SW_SHOWDEFAULT );
	UpdateWindow( hWnd);

}

YGDGame::~YGDGame()
{

}

void YGDGame::initGame()
{
  pEngine->setSkyBoxTexture(".\\Textures\\skybox.dds");
  pInp = getInput();
  pTimer = getTimerInstance();
  paused = true;
  started = false;

  pDebugText = createText(24,255,255,255);
  pDebugText->setPosition(1000,5);

	pCam = createCamera(5.0f,3.0f,3.0f);
  pCam->setYaw(0);
  pCam->setPitch(0);
  pCam->setLookAtPoint(0,0,0);

  pEngine->setCamera(pCam);
  

  //pCam->setPitch(0.2f);
  //pCam->setYaw(1.0f);

  pState = new Logic::CState();
  pState->init();
  
  pMainMenu = createWindow(600,600);

  pMainMenu->setBackgroundImage("MainMenu.bmp",0,1,0);
  float posX = pEngine->getScreenWidth()/2.0f-300.0f;
  float posY = pEngine->getScreenHeight()/2.0f-300.0f;
  pMainMenu->setPosition(posX, posY);
  pMainMenu->setOccupacity(0.3f);
  pMainMenu->setVisible(true);


  

}

void YGDGame::clean()
{
  pTimer = 0;
  delete pCam;

	pEngine->cleanUp();
  delete pEngine;

}

void YGDGame::run()
{
  initGame();
  	 // Enter the message loop
  MSG msg;
  ZeroMemory( &msg, sizeof( msg ) );

  while (TRUE)
	{
	  while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	  {
		  TranslateMessage(&msg);
		  DispatchMessage(&msg);
	  }
    if(msg.message == WM_QUIT)
      break;


    float dT=pTimer->getElapsedTime();

    handleInput(dT);

    doUpdate(dT);

	pEngine->render();
	}
  delete pState;
}

void YGDGame::handleInput(float dT)
{
  if (!paused)
  {
    if (started)
    {
      pState->handleInput(dT);

      if (pInp->isKeyDown(0x1e))
      {
        pCam->strafe(-dT/5*10);
      }
      if (pInp->isKeyDown(0x20))
      {
        pCam->strafe(dT/5*10);
      }
      if (pInp->isKeyDown(0x1f))
      {
        pCam->moveForward(-dT/5*10);
      }
      if (pInp->isKeyDown(0x11))
      {
        pCam->moveForward(dT/5*10);
      }

      pCam->pitch(pInp->getMouseStateY()*0.001f);
      pCam->yaw(pInp->getMouseStateX()*0.001f);

      if (pInp->isKeyPressed(0x39))
      {
                    //pCam->setLookAtPoint(0.0f,0.0f,0.0f);

        paused = true;
        started = false;
        pMainMenu->setVisible(true);
        //pMainMenu->setOccupacity(0.3f);
      }
    }
  }
  else 
  {
    if (pInp->isKeyPressed(0x39))
    {
      started = true;
    }
  }

}


void YGDGame::doUpdate(float dT)
{
  static float st = 0.3f;
  pEngine->update();
  static float accumulator = 0.0f;
  std::ostringstream s;
  float x,y,z;
  pCam->getPos(x,y,z);
  float yaw,pitch,roll;
  pCam->getOrientation(yaw,pitch,roll);
  s << "X: " << x << std::endl << "Y: " << y << std::endl << "Z: " << z << std::endl
    << "yaw: " << yaw << std::endl << "pitch: " << pitch << std::endl << "roll: " << roll;
  //str << pCam->getPos();
  pDebugText->setText(s.str());

  if (!paused)
  {
    if (started)
    {
      float frameTime = pTimer->getElapsedTime();

      if ( frameTime > 0.25f )
      {
                  frameTime = 0.25f;	  // note: max frame time to avoid spiral of death
      }
      accumulator += frameTime;

      while ( accumulator >= 0.01f )
      {
        calculatePhysics(0.01);
        accumulator -= 0.01f;
        pState->updateAllObjects(1.0f);
      }

       pState->updateAllObjects(accumulator/0.1f);
       //pState->updateAllObjects(1.0f);
    }
  }
  else
  {
    if (started && paused) 
    {
      st-=dT;
      pMainMenu->setOccupacity(st);
      if (st <= 0.0f)
      {
        pMainMenu->setOccupacity(0.3f);
        st = 0.3f;
        pMainMenu->setVisible(false);
        paused = false;
      }
    }
  }
}